/************************************************************************ 

  FileName: 
         SM3.h 
  Version: 
         SM3_V1.1 
  Date: 
         Sep 18,2016 
  Description: 
         This headfile provide macro defination, parameter definition 
   and function declaration needed in SM3 algorithm implement 
  Function List: 
    1.SM3_256        //calls SM3_init, SM3_process and SM3_done to calculate hash value 
    2.SM3_init       //init the SM3 state 
    3.SM3_process    //compress the the first len/64 blocks of the message 
    4.SM3_done       //compress the rest message and output the hash value 
    5.SM3_compress   //called by SM3_process and SM3_done, compress a single block of message 
    6.BiToW          //called by SM3_compress,to calculate W from Bi 
    7.WToW1          //called by SM3_compress, calculate W' from W 
    8.CF             //called by SM3_compress, to calculate CF function. 
    9.BigEndian      //called by SM3_compress and SM3_done.GM/T 0004-2012 requires to use 
big-endian. 
                     //if CPU uses little-endian, BigEndian function is a necessary call to 
change the 
                     //little-endian format into big-endian format. 
    10.SM3_SelfTest  //test whether the SM3 calculation is correct by comparing the hash result 
with the standard data 
  History: 
    1. Date:   Sep 18,2016 
       Author: Mao Yingying, Huo Lili 
       Modification: 1)add notes to all the functions 
                     2)add SM3_SelfTest function 
************************************************************************/ 

#include <string.h> 

#define SM3_len 256 
#define SM3_T1 0x79CC4519 
#define SM3_T2 0x7A879D8A 
#define SM3_IVA 0x7380166f 
#define SM3_IVB 0x4914b2b9 
#define SM3_IVC 0x172442d7 
#define SM3_IVD 0xda8a0600 
#define SM3_IVE 0xa96f30bc 
#define SM3_IVF 0x163138aa 
#define SM3_IVG 0xe38dee4d 
#define SM3_IVH 0xb0fb0e4e 

/* Various logical functions */ 
#define SM3_p1(x)        (x^SM3_rotl32(x,15)^SM3_rotl32(x,23)) 
#define SM3_p0(x)        (x^SM3_rotl32(x,9)^SM3_rotl32(x,17)) 
#define SM3_ff0(a,b,c)   (a^b^c) 
#define SM3_ff1(a,b,c)   ((a&b)|(a&c)|(b&c)) 
#define SM3_gg0(e,f,g)   (e^f^g) 
#define SM3_gg1(e,f,g)   ((e&f)|((~e)&g)) 
#define SM3_rotl32(x,n)  ((((unsigned int) x) << n) | (((unsigned int) x) >> (32 - n))) 
#define SM3_rotr32(x,n)  ((((unsigned int) x) >> n) | (((unsigned int) x) << (32 - n))) 

typedef struct { 
    unsigned int  state[8]; 
    unsigned int  length; 
    unsigned int  curlen; 
    unsigned char  buf[64]; 
} SM3_STATE; 

void BiToWj(unsigned int Bi[], unsigned int Wj[]); 
void WjToWj1(unsigned int Wj[], unsigned int Wj1[]); 
void CF(unsigned int Wj[], unsigned int Wj1[], unsigned int V[]); 
void BigEndian(unsigned char src[], unsigned int bytelen, unsigned char des[]); 
void SM3_init(SM3_STATE *md); 
void SM3_compress(SM3_STATE * md); 
void SM3_process(SM3_STATE * md, unsigned char buf[], int len); 
void SM3_done(SM3_STATE *md, unsigned char *hash); 
void SM3_256(unsigned char buf[], int len, unsigned char hash[]); 
int SM3_SelfTest();
